Technotes


Fun With PrJobMerge



Technote PR 16March 1992



Revised by: Matt Deatherage May 1992
Written by: Scott "Zz" Zimmerman and Matt Deatherage March 1992

This Technical Note discusses some interesting behavior you'll encounter while using PrJobMerge with the 7.0 and 7.1 versions of the LaserWriter driver.

Changes since March 1992: Corrected the Vulcan-like "THPring" typo to correctly read "THPrint," and changed a comment in the code to mean what I originally meant.

Like many Printing Manager calls, PrJobMerge is implemented by the currently chosen printer driver. This makes sense after consideration--since the printer driver may store job-specific information anywhere in the print record, only the printer driver can correctly merge this into a destination print record.

The LaserWriter driver's implementation of PrJobMerge has a few bugs in versions 7.0 and 7.1.


Fun Thing #1

Historically, PrJobMerge hasn't worked correctly in the LaserWriter driver. The driver does not correctly merge all job-related data (like the number of copies requested) into the destination print record, so printing multiple copies of multiple documents from the Finder isn't really possible with the LaserWriter driver.

The only possible workaround is to present a different job dialog for each document to be printed, but this isn't recommended--especially since the job dialog doesn't tell you which document you're about to print.

Fun Thing #2

As if this wasn't enough excitement for one driver, in versions 7.0 and 7.1 of the LaserWriter driver PrJobMerge actually manages to destroy all the job-specific information in the source print record after it doesn't copy it into the destination print record.

There is a workaround for this problem--make a copy of the source print record and pass the copy to PrJobMerge. If you pass the copy to PrJobMerge, you can just replace PrJobMerge with your own routine that makes a copy, merges it into the destination, and disposes of the copy. This will work for all printer drivers, although it's necessary only with version 7.0 of the LaserWriter driver.

Such a procedure might look like this in Pascal:

PROCEDURE NewPrJobMerge(hPrintSrc,hPrintDst: THPrint);

    VAR
        copyError: OSErr;
        hPrintTemp: THPrint;

    BEGIN
        hPrintTemp := hPrintSrc;  {make our own copy of the print record handle}
        copyError := HandToHand(Handle(hPrintTemp));
        PrSetError(copyError); {so we can get it later}
        IF copyError = noErr THEN BEGIN
            {hPrintTemp is now a copy of the original source record}
            PrJobMerge(hPrintTemp,hPrintDst); {This messes up hPrintTemp, but we
                                               don't care}
        END; {if copyError = noErr}
        IF hPrintTemp <> NIL THEN DisposHandle(Handle(hPrintTemp)); {only a copy,
                                                                     remember!}
    END;

Don't Go Overboard Trying to Solve This

Although the bugs in PrJobMerge in versions 7.0 and 7.1 of the LaserWriter driver make certain kinds of printing multiple documents impossible without device-specific workarounds, we strongly encourage you not to implement such code. Any code that tries to replicate the function of PrJobMerge must by nature depend on how the LaserWriter driver stores information in the print record, and this is a Bad Thing. The road to Compatibility Hell is paved with good intentions.

If you write your code as described in this Note, it will behave properly when the bug is fixed without change on your part. If you go overboard trying to write your own PrJobMerge function, your application is a prime candidate for compatibility problems.

Further Reference:




Technotes
Previous Technote | Contents | Next Technote